{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 预测波士顿房价"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from keras.datasets import boston_housing\n",
    "\n",
    "(train_data, train_labels), (test_data, test_labels) = boston_housing.load_data()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "404条训练集，102条测试集，其中每个数据都有13个特征值。\n",
    "labels 是房价中位数，单位是千元（美元）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据标准化：\n",
    "将所有数据特征转换到 [-1, 1] 之间范围"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "mean = train_data.mean(axis=0)\n",
    "train_data -= mean\n",
    "std = train_data.std(axis=0)\n",
    "train_data /= std\n",
    "\n",
    "test_data -= mean\n",
    "test_data /= std"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于样本少，用小网络：2层隐藏层，每层64个单元。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from keras import models\n",
    "from keras import layers\n",
    "\n",
    "def build_model():\n",
    "    model = models.Sequential()\n",
    "    model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],)))\n",
    "    model.add(layers.Dense(64, activation='relu'))\n",
    "    model.add(layers.Dense(1))\n",
    "    model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])\n",
    "    return model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数据量较少的场景下，会导致验证分数有很大的波动。可以使用K折验证的方式：将数据划分为多个分区。每个分区分别都做一次验证集。\n",
    "如：数据分割成ABC3个分区。在AB上训练，在C上验证；在BC上训练，在A上验证；在AC上训练，在B上验证。就实现了数据的最大程度利用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "processing fold # 0\n",
      "processing fold # 1\n",
      "processing fold # 2\n",
      "processing fold # 3\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "k = 4\n",
    "size = len(train_data) // k\n",
    "num_epochs = 100\n",
    "all_scores = []\n",
    "\n",
    "for i in range(k):\n",
    "    print('processing fold #', i)\n",
    "    val_data = train_data[i * size: (i + 1) * size]\n",
    "    val_labels = train_labels[i * size : (i + 1) * size]\n",
    "    \n",
    "    partial_train_data = np.concatenate(\n",
    "        [train_data[:i * size],\n",
    "        train_data[(i + 1) * size:]],\n",
    "        axis=0)\n",
    "    partial_train_labels = np.concatenate(\n",
    "        [train_labels[:i * size],\n",
    "        train_labels[(i + 1) * size:]],\n",
    "        axis=0)\n",
    "    \n",
    "    model = build_model()\n",
    "    model.fit(partial_train_data, partial_train_labels, epochs=num_epochs, batch_size=1, verbose=0)\n",
    "    val_mse, val_mae = model.evaluate(val_data, val_labels, verbose=0)\n",
    "    all_scores.append(val_mae)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1.8967717071570973, 2.7043548598147855, 2.700930916436828, 2.213931130890799]"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.3789971535748773"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(all_scores)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "scores的差距较大，结果不可靠。这里吧训练轮次增加到500次。\n",
    "(代码同上，只是把轮次改成了500，fit 的过程增加了验证集数据，每轮记录的数据改成了绝对误差)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "processing fold # 0\n",
      "processing fold # 1\n",
      "processing fold # 2\n",
      "processing fold # 3\n"
     ]
    }
   ],
   "source": [
    "num_epochs = 500\n",
    "all_mae_histories = []\n",
    "\n",
    "for i in range(k):\n",
    "    print('processing fold #', i)\n",
    "    val_data = train_data[i * size: (i + 1) * size]\n",
    "    val_labels = train_labels[i * size : (i + 1) * size]\n",
    "    \n",
    "    partial_train_data = np.concatenate(\n",
    "        [train_data[:i * size],\n",
    "        train_data[(i + 1) * size:]],\n",
    "        axis=0)\n",
    "    partial_train_labels = np.concatenate(\n",
    "        [train_labels[:i * size],\n",
    "        train_labels[(i + 1) * size:]],\n",
    "        axis=0)\n",
    "    \n",
    "    model = build_model()\n",
    "    history = model.fit(partial_train_data, partial_train_labels, validation_data=(val_data, val_labels), epochs=num_epochs, batch_size=1, verbose=0)\n",
    "    mae_history = history.history['val_mean_absolute_error']\n",
    "    all_mae_histories.append(mae_history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "500"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "average_mae_history = [np.mean([x[i] for x in all_mae_histories]) for i in range(num_epochs)]\n",
    "len(average_mae_history)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "plt.plot(range(1, len(average_mae_history) + 1),average_mae_history)\n",
    "plt.xlabel('Epoochs')\n",
    "plt.ylabel('Validation MAE')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def smooth_curve(points, factor=0.9):\n",
    "    smoothed_points = []\n",
    "    for point in points:\n",
    "        if smoothed_points:\n",
    "            previous = smoothed_points[-1]\n",
    "            smoothed_points.append(previous * factor + point * (1 - factor))\n",
    "        else:\n",
    "            smoothed_points.append(point)\n",
    "    return smoothed_points\n",
    "\n",
    "smooth_mae_history = smooth_curve(average_mae_history[10:])\n",
    "\n",
    "plt.plot(range(1, len(smooth_mae_history) + 1), smooth_mae_history)\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Validation MAE')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以从上述调整过的曲线中看出：从80轮开始在验证集上的准确度就开始大幅下滑了，过拟合。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "102/102 [==============================] - 0s 2ms/step\n"
     ]
    }
   ],
   "source": [
    "model = build_model()\n",
    "model.fit(train_data, train_labels, epochs=80, batch_size=16, verbose=0)\n",
    "test_mse_score, test_mae_score = model.evaluate(test_data, test_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.7143025865741803"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_mae_score"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最终的预测和真实数据还是有 $2700 的差距。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
